package xyz.scootaloo.draft.tool

import org.apache.lucene.util.RamUsageEstimator
import org.junit.Test
import xyz.scootaloo.adt.tree.TrieTree
import xyz.scootaloo.adt.tree.TrieTreeJavaEdition
import xyz.scootaloo.util.IOTool

/**
 * 测试几个存储字符串的方式
 * 参考标准: 占用内存, 速度
 *
 * 数据: 2181个常用单词
 *
 * 使用 HashSet
 * 存储: 0ms
 * 读取: 0ms
 * 内存: 127KB
 *
 * 使用第一个Java版本
 * 存储: 0ms
 * 读取: 0ms
 * 内存: 792.6KB
 *
 * 使用Kotlin版本
 * 存储: 3ms
 * 读取: 12ms
 * 内存: 337.4KB
 *
 * @author flutterdash@qq.com
 * @since 2021/4/20 18:11
 */
class TrieTest {

    @Test
    fun testRoot() {
        runTask("HashSet", this::testHashSet)
        runTask("JavaSet", this::testTrieTreeJavaEdition)
        runTask("Kotlin", this::testKotlinEdition)
    }

    private inline fun runTask(taskName: String,
                        task: () -> Unit) {
        println(taskName)
        task()
        println()
    }

    @Test
    fun testHashSet() {
        val set = HashSet<String>()
        val data = getData()
        val saveStart = System.currentTimeMillis()
        for (word in data) {
            set.add(word)
        }
        val saveEnd = System.currentTimeMillis()

        val readStart = System.currentTimeMillis()
        for (word in data) {
            if (!set.contains(word))
                throw RuntimeException("错误")
        }
        val readEnd = System.currentTimeMillis()

        showResult(set, saveStart, saveEnd, readStart, readEnd)
    }

    @Test
    fun testTrieTreeJavaEdition() {
        val set = TrieTreeJavaEdition()
        val data = getData()
        val saveStart = System.currentTimeMillis()
        var idx = 1
        for (word in data) {
            set.add(word)
            idx++
        }
        val saveEnd = System.currentTimeMillis()

        val readStart = System.currentTimeMillis()
        for (word in data) {
            if (!set.contains(word))
                throw RuntimeException("错误")
        }
        val readEnd = System.currentTimeMillis()

        showResult(set, saveStart, saveEnd, readStart, readEnd)
    }

    @Test
    fun testKotlinEdition() {
        val set = TrieTree()
        val data = getData()
        val saveStart = System.currentTimeMillis()
        for (word in data) {
            set.add(word)
        }
        val saveEnd = System.currentTimeMillis()

        val readStart = System.currentTimeMillis()
        for (word in data) {
            if (!set.contains(word))
                throw RuntimeException("错误")
        }
        val readEnd = System.currentTimeMillis()

        showResult(set, saveStart, saveEnd, readStart, readEnd)
    }

    @Test
    fun test0() {
        val set = TrieTree()
        val word = "rim"
        set.add(word)
        println(set.contains(word))
    }


    private fun getData(): List<String> {
        return DATA
    }

    private fun showResult(collection: Any,
                           readStart: Long, readEnd: Long,
                           saveStart: Long, saveEnd: Long) {
        println("存储: ${saveEnd - saveStart}")
        println("读取: ${readEnd - readStart}")
        println("内存: ${RamUsageEstimator.humanSizeOf(collection)}")
    }

    companion object {
        val DATA: List<String> = IOTool.readFileAsList("draft/wordbook.txt")
    }

}
